home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 January: Mac OS SDK / Dev.CD Jan 98 SDK2.toast / Development Kits (Disc 2) / QuickDraw GX / Programming Stuff / GXEdit Library & Doc / GXEditDebug.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-04-10  |  9.5 KB  |  602 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:                GXEditDebug.c
  3.     
  4.     Contains:
  5.     
  6.     Written by:        Barton R. House
  7.     
  8.     Copyright:        © 1993 by Apple Computer, Inc., All rights reserved.
  9.     
  10. */
  11.  
  12. #include "GXEdit.h"
  13. #include "GXEditDoc.h"
  14. #include "GXEditError.h"
  15. #define    _GXEditDebugPrivate_
  16. #include "GXEditDebug.h"
  17.  
  18. #define kCheckAllMagic    0
  19.  
  20. #define kMagic            0x7b
  21. #define kMagicSize        4
  22.  
  23. typedef struct block {
  24.     struct block    ** next;
  25.     struct block    ** prev;
  26.     Boolean            isHandle;
  27.     Boolean            isLocked;
  28.     Boolean            hasMagic;
  29.     union {
  30.         long        l;
  31.         Ptr            p;
  32.         Handle        h;
  33.     } mem;
  34.     unsigned long    size;
  35. } BlockRec, * BlockPtr, ** BlockHan;
  36.  
  37. static BlockHan MyBlocks = nil;
  38.  
  39. static BlockHan        FindBlock(long l);
  40. static void            CheckPtrAccess(Ptr p, unsigned long size);
  41. static void            CheckMagic(BlockHan block);
  42. static void            SetMagic(BlockHan block);
  43.  
  44. void gxEditHLock(Handle h)
  45. {
  46.     BlockHan    block;
  47.     
  48.     block = FindBlock((long) h);
  49.     
  50.     if(block == nil)
  51.         gxEditPostError(nil, gx_edit_internal_fatal_error);
  52.     else {
  53.     
  54.         if((*block)->isLocked)
  55.             gxEditPostError(nil, gx_edit_internal_fatal_error);
  56.         else {
  57.             
  58.             HLock(h);
  59.             
  60.             (*block)->isLocked = true;
  61.             
  62.         }
  63.     
  64.     }
  65.     
  66. }
  67.  
  68. void gxEditHUnlock(Handle h)
  69. {
  70.     BlockHan    block;
  71.     
  72.     block = FindBlock((long) h);
  73.     
  74.     if(block == nil)
  75.         gxEditPostError(nil, gx_edit_internal_fatal_error);
  76.     else {
  77.     
  78.         if(!(*block)->isLocked)
  79.             gxEditPostError(nil, gx_edit_internal_fatal_error);
  80.         else {
  81.             
  82.             HUnlock(h);
  83.             
  84.             (*block)->isLocked = false;
  85.             
  86.         }
  87.     
  88.     }
  89.     
  90. }
  91.  
  92. void gxEditSetHandleSize(Handle h, unsigned long size)
  93. {
  94.     OSErr        err;
  95.     BlockHan    block;
  96.     
  97.     block = FindBlock((long) h);
  98.     
  99.     if(block == nil)
  100.         gxEditPostError(nil, gx_edit_internal_fatal_error);
  101.     else if((*block)->isLocked)
  102.         gxEditPostError(nil, gx_edit_internal_fatal_error);
  103.     else {
  104.         
  105.         (*block)->size = size;
  106.         
  107.         SetHandleSize(h, size + kMagicSize);
  108.         
  109.         if((err = MemError()) != noErr)
  110.             gxEditPostError(nil, gx_edit_internal_fatal_error);
  111.         else
  112.             SetMagic(block);
  113.         
  114.     }
  115. }
  116.  
  117. Handle gxEditNewHandle(long size)
  118. {
  119.     OSErr        err;
  120.     Handle        h;
  121.     long        * ptr;
  122.     long        count;
  123.     BlockHan    block;
  124.     
  125.     h = NewHandle(size + kMagicSize);
  126.     
  127.     if((err = MemError()) != noErr)
  128.         gxEditPostError(nil, gx_edit_internal_fatal_error);
  129.         
  130.     /* intialize with garbage */
  131.     ptr = (long *) *h;
  132.     count = (size + 3)/4;
  133.     while(count--) *ptr++ = 0xABCDEF12;
  134.     
  135.     block = AddBlock((long) h, size, true);
  136.     
  137.     if(block!= nil)
  138.         SetMagic(block);
  139.     
  140.     return(h);
  141. }
  142.  
  143. void gxEditDisposeHandle(Handle h)
  144. {
  145.     OSErr        err;
  146.     BlockHan    block;
  147.     long        * ptr;
  148.     long        size;
  149.     
  150.     block = FindBlock((long) h);
  151.     
  152.     if(block == nil)
  153.         gxEditPostError(nil, gx_edit_internal_fatal_error);
  154.     else {
  155.     
  156.         if((*block)->isLocked)
  157.             gxEditPostError(nil, gx_edit_internal_fatal_error);
  158.     
  159.         RemoveBlock((long) h);
  160.         
  161.         /* intialize with garbage */
  162.         size = GetHandleSize(h);
  163.         ptr = (long *) *h;
  164.         size = (size + 3)/4;
  165.         while(size--) *ptr++ = 0xABCDEF12;
  166.         
  167.         DisposeHandle(h);
  168.         
  169.         if((err = MemError()) != noErr)
  170.             gxEditPostError(nil, gx_edit_internal_fatal_error);
  171.             
  172.     }
  173.         
  174. }
  175.  
  176. Ptr gxEditNewPtr(long size)
  177. {
  178.     OSErr        err;
  179.     Ptr            p;
  180.     long        * ptr;
  181.     long        count;
  182.     BlockHan    block;
  183.     
  184.     p = NewPtr(size + kMagicSize);
  185.     
  186.     if((err = MemError()) != noErr)
  187.         gxEditPostError(nil, gx_edit_internal_fatal_error);
  188.         
  189.     /* intialize with garbage */
  190.     
  191.     ptr = (long *) p;
  192.     count = (size + 3)/4;
  193.     while(count--) *ptr++ = 0xABCDEF12;
  194.     
  195.     block = AddBlock((long) p, size, false);
  196.     
  197.     if(block!= nil)
  198.         SetMagic(block);
  199.     
  200.     return(p);
  201. }
  202.  
  203. void gxEditDisposePtr(Ptr p)
  204. {
  205.     OSErr        err;
  206.     BlockHan    block;
  207.     long        * ptr;
  208.     long        size;
  209.     
  210.     block = FindBlock((long) p);
  211.     
  212.     if(block == nil)
  213.         gxEditPostError(nil, gx_edit_internal_fatal_error);
  214.     else {
  215.         
  216.         size = (*block)->size;
  217.         
  218.         RemoveBlock((long) p);
  219.         
  220.         /* intialize with garbage */
  221.  
  222.         ptr = (long *) p;
  223.         size = (size + 3)/4;
  224.         while(size--) *ptr++ = 0xABCDEF12;
  225.         
  226.     }
  227.     
  228.     DisposePtr(p);
  229.     
  230.     if((err = MemError()) != noErr)
  231.         gxEditPostError(nil, gx_edit_internal_fatal_error);
  232.         
  233. }
  234.  
  235. void gxEditPtrAndHand(Ptr p, Handle h, unsigned long size)
  236. {
  237.     OSErr        err;
  238.     BlockHan    block;
  239.     
  240.     block = FindBlock((long) h);
  241.     
  242.     if(block == nil)
  243.         gxEditPostError(nil, gx_edit_internal_fatal_error);
  244.     else {
  245.     
  246.         SetHandleSize(h, (*block)->size + size + kMagicSize);
  247.  
  248.         if((err = MemError()) != noErr)
  249.             gxEditPostError(nil, gx_edit_internal_fatal_error);
  250.         else {
  251.         
  252.             BlockMove(p, (Ptr) (*h + (*block)->size), size);
  253.             (*block)->size += size;
  254.             
  255.             SetMagic(block);
  256.             
  257.         }
  258.         
  259.     }
  260.         
  261.         
  262. }
  263.  
  264. void gxEditHandToHand(Handle *h)
  265. {
  266.     OSErr        err;
  267.     BlockHan    block;
  268.     long        size;
  269.     
  270.     block = FindBlock((long) *h);
  271.     
  272.     if(block == nil)
  273.         gxEditPostError(nil, gx_edit_internal_fatal_error);
  274.     else {
  275.     
  276.         HandToHand(h);
  277.         
  278.         if((err = MemError()) != noErr)
  279.             gxEditPostError(nil, gx_edit_internal_fatal_error);
  280.         else {
  281.         
  282.             size = GetHandleSize((Handle) *h);
  283.                 
  284.             if((err = MemError()) != noErr)
  285.                 gxEditPostError(nil, gx_edit_internal_fatal_error);
  286.             else {
  287.             
  288.                 if(!(*block)->hasMagic)
  289.                     SetHandleSize((Handle) *h, size + kMagicSize);
  290.                 else
  291.                     size -= kMagicSize;
  292.             
  293.                 if((err = MemError()) != noErr)
  294.                     gxEditPostError(nil, gx_edit_internal_fatal_error);
  295.                 else {
  296.                 
  297.                     block = AddBlock((long) *h, size, true);
  298.                     
  299.                     if(block!= nil)
  300.                         SetMagic(block);
  301.                         
  302.                 }
  303.                     
  304.             }
  305.     
  306.         }
  307.         
  308.     }
  309.         
  310. }
  311.  
  312. void gxEditPtrToHand(Ptr p, Handle *h, unsigned long size)
  313. {
  314.     OSErr        err;
  315.     BlockHan    block;
  316.  
  317.     block = FindBlock((long) p);
  318.     
  319.     if(block == nil)
  320.         gxEditPostError(nil, gx_edit_internal_fatal_error);
  321.     else {
  322.     
  323.         PtrToHand(p, h, size);
  324.         
  325.         if((err = MemError()) != noErr)
  326.             gxEditPostError(nil, gx_edit_internal_fatal_error);
  327.         else {
  328.                     
  329.             SetHandleSize((Handle) *h, size + kMagicSize);
  330.         
  331.             if((err = MemError()) != noErr)
  332.                 gxEditPostError(nil, gx_edit_internal_fatal_error);
  333.             else {
  334.             
  335.                 block = AddBlock((long) *h, size, true);
  336.                 
  337.                 if(block!= nil)
  338.                     SetMagic(block);
  339.                     
  340.             }
  341.  
  342.         }
  343.         
  344.     }
  345.         
  346. }
  347.  
  348. void gxEditBlockMove(Ptr src, Ptr dst, unsigned long size)
  349. {
  350.  
  351.     if(size == 0)
  352.         return;
  353.         
  354.     CheckPtrAccess(src, size);
  355.     CheckPtrAccess(dst, size);
  356.     
  357.     BlockMove(src, dst, size);
  358.     
  359. }
  360.  
  361. long gxEditGetHandleSize(Handle h)
  362. {
  363.     BlockHan            block;
  364.     unsigned long        size;
  365.     
  366.     block = FindBlock((long) h);
  367.     
  368.     if(block == nil) {
  369.     
  370.         gxEditPostError(nil, gx_edit_internal_fatal_error);
  371.         size = 0;
  372.         
  373.     } else
  374.         size = (*block)->size;
  375.     
  376.     return(size);
  377.     
  378. }
  379.  
  380. static BlockHan FindBlock(long l)
  381. {
  382.     BlockHan    block;
  383.         
  384.     block = MyBlocks;
  385.     
  386. #if kCheckAllMagic
  387.  
  388.     while(block != nil) {
  389.         
  390.         CheckMagic(block);
  391.             
  392.         block = (*block)->next;
  393.         
  394.         
  395.     }
  396.     
  397. #endif
  398.  
  399.     block = MyBlocks;
  400.     
  401.     while(block != nil) {
  402.         
  403.         if((*block)->mem.l == l) {
  404.             CheckMagic(block);
  405.             return(block);
  406.         }
  407.             
  408.         block = (*block)->next;
  409.         
  410.         
  411.     }
  412.     
  413.     return(nil);
  414. }
  415.  
  416. void * AddBlock(long l, unsigned long size, Boolean isHandle)
  417. {
  418.     BlockHan    blockHan;
  419.     BlockPtr    block;
  420.     OSErr        err;
  421.     
  422.     blockHan = (BlockHan) NewHandle(sizeof(BlockRec));
  423.     
  424.     if((err = MemError()) != noErr) {
  425.         gxEditPostError(nil, gx_edit_internal_fatal_error);
  426.         return;
  427.     }
  428.     
  429.     block = *blockHan;
  430.     
  431.     block->mem.l = l;
  432.     block->size = size;
  433.     block->isHandle = isHandle;
  434.     block->isLocked = false;
  435.     block->hasMagic = false;
  436.     
  437.     block->next = MyBlocks;
  438.     block->prev = nil;
  439.     
  440.     if(block->next != nil)
  441.         (*block->next)->prev = blockHan;
  442.     
  443.     MyBlocks = blockHan;
  444.     
  445.     return((void *) blockHan);
  446.     
  447. }
  448.  
  449. void RemoveBlock(long l)
  450. {
  451.     BlockHan        blockHan;
  452.     BlockPtr        block;
  453.         
  454.     blockHan = FindBlock(l);
  455.     
  456.     if(blockHan == nil) {
  457.         gxEditPostError(nil, gx_edit_internal_fatal_error);
  458.         return;
  459.     }
  460.     
  461.     block = *blockHan;
  462.     
  463.     if(block->prev == nil) {
  464.         
  465.         if(MyBlocks != blockHan) {
  466.             gxEditPostError(nil, gx_edit_internal_fatal_error);
  467.             return;
  468.         }
  469.         
  470.         MyBlocks = block->next;
  471.     
  472.     } else
  473.         (*block->prev)->next = block->next;
  474.  
  475.     if(block->next != nil)
  476.         (*block->next)->prev = block->prev;
  477.         
  478.     DisposeHandle((Handle) blockHan);
  479.         
  480. }
  481.  
  482. static BlockHan FindAddress(Ptr p)
  483. {
  484.     BlockHan    block;
  485.     Ptr            mem;
  486.     
  487.     p = StripAddress(p);
  488.     
  489.     block = MyBlocks;
  490.     
  491.     while(block != nil) {
  492.     
  493.         if((*block)->isHandle) {
  494.         
  495.             mem = StripAddress(*(*block)->mem.h);
  496.             
  497.             if(mem <= p && mem + (*block)->size > p)
  498.                 return(block);
  499.                 
  500.         } else {
  501.         
  502.             mem = StripAddress((*block)->mem.p);
  503.             
  504.             if(mem <= p && mem + (*block)->size > p)
  505.                 return(block);
  506.                 
  507.         }
  508.     
  509.         block = (*block)->next;
  510.         
  511.     }
  512.     
  513.     gxEditPostError(nil, gx_edit_internal_fatal_error);
  514.     
  515.     return(nil);
  516.     
  517. }
  518.  
  519. static void CheckPtrAccess(Ptr p, unsigned long size)
  520. {
  521.     BlockHan        block;
  522.     Ptr                mem;
  523.     
  524.     p = StripAddress(p);
  525.  
  526.     if(p < (Ptr) SetCurrentA5()  &&  p > (Ptr) &p)
  527.         return;                            /* stack variable */
  528.         
  529.     if(p < (Ptr) GetZone() || p > (Ptr) GetApplLimit()) {
  530.         gxEditPostError(nil, gx_edit_internal_fatal_error);
  531.         return;
  532.     }
  533.     
  534.     block = FindAddress(p);
  535.     
  536.     if(block == nil)
  537.         return;
  538.     
  539.     if((*block)->isHandle) {
  540.     
  541.         mem = StripAddress(*(*block)->mem.h);
  542.         
  543.         if((p+size) > (mem + (*block)->size)) {
  544.             gxEditPostError(nil, gx_edit_internal_fatal_error);
  545.             return;
  546.         }
  547.         
  548.     } else {
  549.     
  550.         mem = StripAddress((*block)->mem.p);
  551.         
  552.         if((p+size) > (mem + (*block)->size)) {
  553.             gxEditPostError(nil, gx_edit_internal_fatal_error);
  554.             return;
  555.         }
  556.         
  557.     }
  558.     
  559. }
  560.  
  561. static void SetMagic(BlockHan block)
  562. {
  563.     char        * magic;
  564.     short        count;
  565.     
  566.     if((*block)->isHandle)
  567.         magic = (char *) ((*(*block)->mem.h) + (*block)->size);
  568.     else
  569.         magic = (char *) ((*block)->mem.p + (*block)->size);
  570.     
  571.     count = kMagicSize;
  572.     
  573.     while(count--)
  574.         *magic++ = kMagic;
  575.         
  576.     (*block)->hasMagic = true;
  577.  
  578. }
  579.  
  580. static void CheckMagic(BlockHan block)
  581. {
  582.     char        * magic;
  583.     short        count;
  584.     
  585.     if(!(*block)->hasMagic)
  586.         return;
  587.         
  588.     if((*block)->isHandle)
  589.         magic = (char *) ((*(*block)->mem.h) + (*block)->size);
  590.     else
  591.         magic = (char *) ((*block)->mem.p + (*block)->size);
  592.     
  593.     count = kMagicSize;
  594.     
  595.     while(count--)
  596.         if(*magic++ != kMagic)
  597.             gxEditPostError(nil, gx_edit_internal_fatal_error);
  598.             
  599. }
  600.  
  601.  
  602.